package com.vf.cloud.api.biz.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.vf.cloud.common.constant.Cache;
import com.vf.cloud.common.datasource.annotation.Tx;
import com.vf.cloud.common.domain.Server;
import com.vf.cloud.common.pool.ProssPool;
import com.vf.cloud.common.util.R;
import com.vf.cloud.common.util.UuidUtil;
import com.vf.cloud.common.vo.RelayVo;
import com.vf.cloud.server.relay.RelayServer;
import com.vf.cloud.server.signalling.SignallingServer;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RestController
@RequestMapping("/server")
public class ServerController {

	@GetMapping(value = { "/list" }, produces = "application/json; charset=utf-8")
	public R<Page<Server>> findList(
			@RequestParam(name = "keywords", required = false, defaultValue = "") String keywords,
			@RequestParam(name = "status", required = false, defaultValue = "") String status,
			@RequestParam(name = "cur", required = false, defaultValue = "1") int cur,
			@RequestParam(name = "limit", required = false, defaultValue = "10") int limit) throws Exception {

		String sqlExceptSelect = " FROM " + Server.TABLE_NAME + " o  WHERE 1=1 ";
		if (!StrKit.isBlank(keywords)) {
			sqlExceptSelect += " AND ( O.NAME LIKE '%" + keywords + "%' ) ";
		}
		sqlExceptSelect += "  ORDER BY   O.UPDATE_TIME asc ";
		Page<Server> pages = Server.dao.paginate(cur, limit, "select * ", sqlExceptSelect);

		for (Server s : pages.getList()) {
			if (StrKit.equals("signaling", s.getType())) {
				s.setStatus(SignallingServer.getInstance().getStatus()+"");
			} else if (StrKit.equals("relay", s.getType())) {
				JSONObject object = JSONObject.parseObject(s.getConfig());
				if (object != null && object.containsKey("stunPort")) {
					if (!StrKit.isBlank(ProssPool.getPid(object.getString("stunPort")))) {
						s.setStatus("2");
						continue;
					}
				}
				s.setStatus("0");
			}
		}
		return R.ok(pages);
	}

	@Tx
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public R<Server> save(Server model) {
		try {
			if (StrKit.isBlank(model.getName())) {
				return R.failed("名称不可以为空！");
			}
			if (StrKit.notBlank(model.getId())) {
				if (model.update()) {
					return R.ok(model);
				} else {
					return R.failed("更新失败！");
				}
			} else {
				model.setId(UuidUtil.getUUID());
				if (model.save()) {
					return R.ok(model);
				} else {
					return R.failed("保存失败！");
				}
			}
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@Tx
	@RequestMapping(value = "/deleteById", method = RequestMethod.GET)
	public R<String> deleteById(@RequestParam(name = "id") String id) throws Exception {
		try {
			Server sever = Server.dao.findById(id);
			if (sever == null)
				return R.failed("数据不存在，刷新后尝试!");
			if (sever.delete()) {
				if (StrKit.equals("signaling", sever.getType())) {
					SignallingServer.getInstance().stop();
					Cache.signalling = null;
				} else if (StrKit.equals("relay", sever.getType())) {
					RelayServer.getInstance().stop();
					Cache.relay = null;
				}
				return R.ok();
			}
			return R.failed("失败！");
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@RequestMapping(value = "/getById", method = RequestMethod.GET)
	public R<Server> getById(@RequestParam(name = "id") String id) throws Exception {
		try {
			Server sever = Server.dao.findById(id);
			if (sever == null)
				return R.failed("数据不存在，刷新后尝试!");
			return R.ok(sever);
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@RequestMapping(value = "/createSignalingServer", method = RequestMethod.GET)
	public R<String> createSignalingServer() throws Exception {
		try {
			Server server = Server.dao.findFirst("select * from " + Server.TABLE_NAME + " where type='signaling'");
			if (server != null) {
				return R.failed("信令服务已经存在.");
			}
			server = new Server();
			server.setId(UuidUtil.getUUID());
			server.setName("信令服务");
			server.setType("signaling");
			server.setStatus("0");
			if (server.save()) {
				return R.ok("信令服务已经创建，请点击编辑按钮完成设置.");
			}
			return R.failed("信令服务创建失败.");
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@RequestMapping(value = "/createRelayServer", method = RequestMethod.GET)
	public R<String> createRelayServer() throws Exception {
		try {
			Server server = Server.dao.findFirst("select * from " + Server.TABLE_NAME + " where type='relay'");
			if (server != null) {
				return R.failed("中继服务已经存在.");
			}
			server = new Server();
			server.setId(UuidUtil.getUUID());
			server.setName("中继服务");
			server.setType("relay");
			server.setStatus("0");
			if (server.save()) {
				return R.ok("中继服务已经创建，请点击编辑按钮完成设置.");
			}
			return R.failed("中继服务创建失败.");
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@RequestMapping(value = "/restartServer", method = RequestMethod.GET)
	public R<String> restartServer(@RequestParam(name = "id") String id) throws Exception {
		try {
			Server sever = Server.dao.findById(id);
			if (sever == null) {
				return R.failed("数据不存在，刷新后尝试.");
			}
			if (StrKit.equals("signaling", sever.getType())) {
				
				JSONObject object = JSONObject.parseObject(sever.getConfig());
				if (StrKit.isBlank(sever.getConfig())) {
					return R.failed("参数不完整，请编辑完善后执行此操作.");
				}

				if (!SignallingServer.getInstance().verify(object)) {
					return R.failed("参数不完整，请编辑完善后执行此操作.");
				}
				SignallingServer.getInstance().restart(sever);
				return R.ok("执行重启指令成，请30秒刷新查看.");
			} else if (StrKit.equals("relay", sever.getType())) {

				if (StrKit.isBlank(sever.getConfig())) {
					return R.failed("参数不完整，请编辑完善后执行此操作.");
				}

				JSONObject object = JSONObject.parseObject(sever.getConfig());
				if (!RelayServer.getInstance().verify(object)) {
					return R.failed("参数不完整，请编辑完善后执行此操作.");
				}

				RelayVo relayVo = new RelayVo();
				relayVo.setId(sever.getId());
				relayVo.setIp(object.getString("ip"));
				relayVo.setStunPort(object.getInteger("stunPort"));
				relayVo.setTurnPort(object.getInteger("turnPort"));
				relayVo.setEnabled(object.getString("enabled"));
				relayVo.setUsername(object.getString("username"));
				relayVo.setPassword(object.getString("password"));
				relayVo.setEnabled(sever.getEnabled());
				RelayServer.getInstance().restart(relayVo);

				return R.ok("执行重启指令成，请30秒刷新查看.");
			}
			return R.failed("未知服务.");
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@RequestMapping(value = "/stop", method = RequestMethod.GET)
	public R<String> stop(@RequestParam(name = "id") String id) throws Exception {
		try {
			Server sever = Server.dao.findById(id);
			if (sever == null) {
				return R.failed("数据不存在，刷新后尝试!");
			}
			if (StrKit.equals("signaling", sever.getType())) {
				

				int status=SignallingServer.getInstance().getStatus();
				if(2!=status) {
					if(-1==status) {
						return R.failed("服务不可用.");
					}
					else if(1==status) {
						return R.failed("服务正在启动中，请启动完成后再操作.");
					}
					else if(0==status) {
						return R.failed("服务已停止，本次操作无效.");
					}
					else if(3==status) {
						return R.failed("服务停止中，本次操作无效.");
					}
				}
				
				if(Cache.signalling!=null) {
					Cache.signalling .setEnbaled("0");
				}
				
				SignallingServer.getInstance().stop();
				return R.ok("发送命令成功，请稍后.");
			} else if (StrKit.equals("relay", sever.getType())) {
				RelayServer.getInstance().stop();
				return R.ok("发送命令成功，请稍后.");
			}
			return R.failed("未知服务.");
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

}
